public class OpenCustomGuiPacket {
public static final Identifier ID = new Identifier(TheClassicofMountainsandOceans.MOD_ID,"opengui");
public static void sendToClient(ServerPlayerEntity player) {
PacketByteBuf buf = new PacketByteBuf(Unpooled.buffer());
ServerPlayNetworking.send(player, ID, buf);
}
public static void registerReceiver() {
ClientPlayNetworking.registerGlobalReceiver(ID, (client, handler, buf, responseSender) -> {
client.execute(() -> {
MinecraftClient.getInstance().setScreen(new CustomScreen(
new CustomScreenHandler(0, MinecraftClient.getInstance().player.getInventory()),
MinecraftClient.getInstance().player.getInventory(),
MinecraftClient.getInstance().player.getName()
));
});
});
}
}
自定義畫面顯示到這邊就差不多完成了,我們可以打開遊戲畫面來看一下成果
接下來我們需要再與村民互動的原始碼中插入我們自己的程式碼,並且攔截原本與村民互動的程式。
@Mixin(VillagerEntity.class)
public class TradeRenderMixin {
@Inject(method = "interactMob",
at = @At(value = "INVOKE",
target = "Lnet/minecraft/entity/passive/VillagerEntity;beginTradeWith(Lnet/minecraft/entity/player/PlayerEntity;)V",shift = At.Shift.BEFORE),
cancellable = true)
private void beforeBeginTradeWith(PlayerEntity player, Hand hand, CallbackInfoReturnable<ActionResult> cir) {
if (!player.getWorld().isClient()) { // 确保这是在服务器端
if (player instanceof ServerPlayerEntity serverPlayer) {
OpenCustomGuiPacket.sendToClient(serverPlayer);
cir.setReturnValue(ActionResult.SUCCESS); // 阻止默认交易行为
cir.cancel();
}
}
}
}
首先我們Mixin的目標是VillagerEntity,這是村民的程式所在,我們在這個村民類別中的interactMob方法中插入我們得程式,並且這個程式的目標位子我們透過閱讀程式的ByteCode來鎖定,剩下的內容明天說